﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TP2.Lib;
using System.Xml.Serialization;

namespace TP2.Lib
{
    //[XmlInclude(typeof(ElementoJuego))]
  [Serializable]
    public abstract class ElementoJuego
    {
        #region /*---------------Propiedades--------------*/

        private int[] _dimensiones = new int[3];
        public int[] Dimensiones
        {
            get { return this._dimensiones; }
            set { this._dimensiones = value; }
        }

        private double[] _posicion = new double[3];
        public double[] Posicion
        {
            get { return this._posicion; }
            set { this._posicion = value;}
        }

        private double _radio;
        public double Radio
        {
            get {return this._radio; }
            set { this._radio = value; }
        }

        private int _vida;
        public int Vida
        {
            get { return this._vida; }
            set { this._vida = value; }
        }

        private int _rapidez;
        public int Rapidez
        {
            get {return this._rapidez;}
            set { this._rapidez = value;}
        }

        private TrayectoriaAbstracta _recorrido;
        public TrayectoriaAbstracta Recorrido
        {
            get { return (this._recorrido); }
            set { this._recorrido = value; }
        }

        public bool EstoyVivo()
        {
            return (this.Vida > 0);
        }

        #endregion


        public ElementoJuego() { }

       // [XmlInclude(typeof(ClaseHija))] //pero cual hija en el caso de tener mas de una?? y en cual constructor?en ambos?
        public ElementoJuego(double[] posInicial, int[] dimensionesEscenario)
        {
            this.Dimensiones = dimensionesEscenario;
            this.Posicion = posInicial;
        }

        public void ModificarVida(int cambio)
        {
            int temp;
            if (cambio < 0)
            {
                temp = this.Vida + Math.Abs(cambio);
            }
            else
            {
                temp = this.Vida - cambio;
            }
            if (temp <= 0) { this.Vida = 0; } //analizar la utilidad de este if
            else { this.Vida = temp; }            
        }

        /* Clacula la distancia que hay entre el elemento invocante y el elemento pasado por parametro, ambos considerados como cuerpos puntuales*/
        public double CalcularDistancia(ElementoJuego elemento)
        {
            double distancia;
            distancia = Math.Sqrt(Math.Pow((elemento.Posicion[0] - this.Posicion[0]), 2) + Math.Pow((elemento.Posicion[1] - this.Posicion[1]), 2));
            return (distancia);
        }

        /* Clacula la distancia que hay entre los dos elementos pasados por parametro ambos considerados como cuerpos extesos con un radio*/
        public double CalcularDistanciaEntreElementos(ElementoJuego elemento2)
        {
            double distancia = this.CalcularDistancia(elemento2) - ((this.Radio) + (elemento2.Radio));
            return distancia;
        }

        #region /*-------Metodos Abstractos---------*/

        public abstract Proyectil Actuar();
        
        public abstract void Impactar(ElementoJuego impactante);
        
        public abstract bool ImpactarConProyectil(Proyectil impactante);
        
        public abstract void ImpactarConArma(Arma impactante);
        
        public abstract void ImpactarConAvionCivil();
        
        public abstract void ImpactarConAvionEnemigo();
        
        public abstract void ImpactarConAvionJugador();
        
        public abstract void ImpactarConHelicopteroPolicia();
        
        public abstract void ImpactarConTanqueEnergia(TanqueEnergia impactante);

        #endregion

    }
}
